package com.huayue.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.alipay.api.AlipayApiException;
import com.huayue.dao.AliPayDao;
import com.huayue.dao.WebInfoDao;
import com.huayue.entity.*;
import com.huayue.service.RoomPredictOrderService;
import com.huayue.service.RoomTypeService;
import com.huayue.service.TempOrderService;
import com.huayue.service.WebInfoService;
import com.huayue.util.DateHelper;
import com.huayue.util.OrderNumberHelper;

/**
 * 网站前台用/支付宝支付模块
 */
@Controller
@RequestMapping("/desk")
public class WebDeskController {

    @Autowired
    WebInfoService svc;

    @Autowired
    RoomTypeService rtsvc;

    @Autowired
    TempOrderService tepsvc;
    @Autowired
    RoomPredictOrderService rpdsvc;

    AliPayDao aliPayDao = new AliPayDao();

    @RequestMapping("/welcome")
    public String welcome(Reserve reserve, HttpServletRequest request) {
        request.setAttribute("reserve", reserve);
        request.setAttribute("info", svc.findAll().get(0));
        request.setAttribute("roomType", rtsvc.findRoomType(reserve, 0));
        return "desk/index";
    }

    @RequestMapping("/reservation")
    public String reservation(HttpServletRequest request, Reserve reserve) {

        request.setAttribute("info", svc.findAll().get(0));
        request.setAttribute("roomType", rtsvc.findRoomType(reserve, 0));
        return "desk/best-rooms";
    }

    @RequestMapping("/reserveOne")
    public String reserveOne(Reserve reserve, Integer id, HttpServletRequest request) {
        request.setAttribute("info", svc.findAll().get(0));
        request.setAttribute("reserve", reserve);
        request.setAttribute("roomType", rtsvc.findRoomType(reserve, id));
        RoomType rt = new RoomType();
        rt.setId(id);
        request.setAttribute("roomInfo", rtsvc.findOne(rt));
        return "desk/best-rooms-detail";
    }

    @RequestMapping("/about")
    public String about(HttpServletRequest request) {
        request.setAttribute("info", svc.findAll().get(0));
        return "desk/about-us";
    }

    @RequestMapping("/findOrder")
    public String findOrder(HttpServletRequest request) {
        request.setAttribute("info", svc.findAll().get(0));
        return "desk/findOrder";
    }

    @RequestMapping(value = "/findNowPredictOrder", method = RequestMethod.POST)
    public String findNowPredictOrder(String phone, Reserve reserve, HttpServletRequest request) {
        request.setAttribute("info", svc.findAll().get(0));
        // 2.根据alipay中一条数据查询temp_order中的一条数据的predice_order_id
        // 3. 根据predict_order_id 查询room_predict_order中的一条数据
        List<Map<String, Object>> mp = rpdsvc.findPredictOrderByPhone(phone);
        request.setAttribute("orders", mp);
        request.setAttribute("roomType", rtsvc.findRoomType(reserve, 0));
        return "desk/order-success";
    }

    @Autowired
    RoomTypeService roomTypeService;

    @RequestMapping(value = "/deskAddOrder", method = RequestMethod.POST)
    public void deskAddOrder(RoomPredictDesk roomPredictDesk, HttpServletResponse response, HttpServletRequest request)
        throws IOException, AlipayApiException {
        // 计算该订单需要缴纳的金额
        roomPredictDesk.getRoomNumber();
        RoomType roomType = new RoomType();
        roomType.setId(roomPredictDesk.getTypeId());
        String onePrice = roomTypeService.getDao().findOne(roomType).get("price").toString();
        BigDecimal typePrice = new BigDecimal(onePrice);
        int day = DateHelper.getDateRangeNumber(roomPredictDesk.getInDate(), roomPredictDesk.getOutDate());

        BigDecimal totalPrice = typePrice.multiply(BigDecimal.valueOf(roomPredictDesk.getRoomNumber()));
        totalPrice = totalPrice.multiply(new BigDecimal(day));
        roomPredictDesk.setTotalPrice(totalPrice);
        String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String seconds = new SimpleDateFormat("HHmmss").format(new Date());
        roomPredictDesk.setTempOrder(date + seconds);
        // 一、 将订单信息存入temp_order表
        TempOrder tempOrder = new TempOrder();
        tempOrder.setName(roomPredictDesk.getName());
        tempOrder.setPhone(roomPredictDesk.getPhone());
        tempOrder.setRemark(roomPredictDesk.getIdNumber());
        tempOrder.setRoom_type_id(roomPredictDesk.getTypeId());
        tempOrder.setRoom_number(roomPredictDesk.getRoomNumber());
        tempOrder.setIn_date(roomPredictDesk.getInDate());
        tempOrder.setOut_date(roomPredictDesk.getOutDate());
        tempOrder.setTotal_price(roomPredictDesk.getTotalPrice());
        tempOrder.setTemp_order(date + seconds);
        tepsvc.insert(tempOrder);
        String temp = "http://" + request.getServerName() + ":80" + request.getContextPath();
        if ("localhost".equals(request.getServerName())) {
            WebInfoDao dao = new WebInfoDao();
            Map<String, Object> map = dao.findOne(null);
            temp = "http://" + map.get("domain").toString() + ":80" + request.getContextPath();
        }
        String notifyUrl = temp + "/desk/notifyUrl";
        String returnUrl = temp + "/desk/returnUrl";
        aliPayDao.SendAliPay(date + seconds, totalPrice, "华悦假日酒店", returnUrl, notifyUrl, response);
        // System.out.println(roomPredictDesk);
    }

    /**
     * 买家付款完成后进行的自动跳转
     * 
     * @param request
     * @param aliPayAccept
     * @return
     * @throws Exception
     */
    @RequestMapping("/returnUrl")
    public String returnUrl(HttpServletRequest request, AliPayAccept aliPayAccept) throws Exception {
        // System.out.println("return:" + aliPayAccept);
        // System.out.println("买家付款完成以后进行自动跳转，因此只会进行一次");
        // 三、
        // boolean b = aliPayDao.AcceptAliPay(request);
        // 1.根据out_trade_no 查询alipay中的一条数据

        // 2.根据alipay中一条数据查询temp_order中的一条数据的predice_order_id
        Map<String, Object> map = tepsvc.findPredictOrderId(aliPayAccept.getOut_trade_no().toString());
        // 3. 根据predict_order_id 查询room_predict_order中的一条数据
        // Map<String, Object> mp = tepsvc.findId(map.get("predict_order_id").toString());
        List<Map<String, Object>> mp = rpdsvc.findPredictOrderByPhone(map.get("phone").toString());
        // 4. 将这条数据在order-success页面上显示出响应信息。
        request.setAttribute("info", svc.findAll().get(0));
        request.setAttribute("orders", mp);
        return "desk/order-success";
    }

    /**
     * 当用户支付成功后进入此方法
     * 
     * @param request
     * @param response
     * @param aliPayAccept
     * @throws Exception
     */
    @RequestMapping("/notifyUrl")
    public void notifyUrl(HttpServletRequest request, HttpServletResponse response, AliPayAccept aliPayAccept)
        throws Exception {
        // System.out.println("notify:" + aliPayAccept);
        if ("TRADE_SUCCESS".equals(aliPayAccept.getTrade_status())) {
            // 二、 开始处理预定业务
            // 1. 根据aliPayAccept中out_trade_no的查询temp_order表中temp_order列，获取到本订单的信息
            Map<String, Object> map = tepsvc.findTempOrder(aliPayAccept.getOut_trade_no());
            // 将支付信息存入alipay表中
            aliPayAccept.setOrderNumber(map.get("id").toString());
            aliPayDao.insert(aliPayAccept);
            // 2. 查询本订单信息中的房间类型对应的可用房间信息
            List<Map<String, Object>> list = tepsvc.findTempOrderNullRoom(map.get("room_type_id").toString());
            String[] rid = new String[Integer.valueOf(map.get("room_number").toString())];

            // 3. 选择订单房间数量的房间id(需要临时存储)
            for (int i = 0; i < rid.length; i++) {
                rid[i] = list.get(i).get("id").toString();

            }
            // 4.封装数据RoomPredictOrder orderInfo(调用orderNumberHelper中的生成订单号，存入对象后销毁该订单号),
            RoomPredictOrder orderInfo = new RoomPredictOrder();
            String order = OrderNumberHelper.getOrderNumber(OrderNumberHelper.YDDORDER, "YDD");
            orderInfo.setOrderNumber(order);
            orderInfo.setTotalPrice(new BigDecimal(aliPayAccept.getBuyer_pay_amount()));
            orderInfo.setPredictInTime(DateHelper.StringToDate(map.get("in_date").toString()));
            orderInfo.setPredictOutTime(DateHelper.StringToDate(map.get("out_date").toString()));
            int roomNumber = Integer.valueOf(map.get("room_number").toString());
            orderInfo.setRemark("网站前台预定");
            OrderNumberHelper.removeOrderNumber(OrderNumberHelper.YDDORDER, order);
            // 单价 = 总金额/总天数/房间数量
            BigDecimal onePrice = new BigDecimal("0");
            onePrice = new BigDecimal(aliPayAccept.getBuyer_pay_amount()).divide(new BigDecimal(roomNumber));
            int day = DateHelper.getDateRangeNumber(orderInfo.getPredictInTime(), orderInfo.getPredictOutTime());
            onePrice = onePrice.divide(new BigDecimal(day));
            // List<RoomPredictOrderDetails> details, Customer cus
            List<RoomPredictOrderDetails> details = new ArrayList<RoomPredictOrderDetails>();
            for (int j = 0; j < roomNumber; j++) {
                RoomPredictOrderDetails rpdo = new RoomPredictOrderDetails();
                rpdo.setRoomTypeId(Long.valueOf(map.get("room_type_id").toString()));
                rpdo.setRoomId(Long.valueOf(rid[j]));
                rpdo.setPrice(onePrice);
                details.add(rpdo);
            }
            Customer cus = new Customer();
            cus.setRealname(map.get("name").toString());
            cus.setIdnumber(map.get("remark").toString());
            cus.setPhone(map.get("phone").toString());
            cus.setSex("0");
            // 5.调用RoomPredictOrderService中addDetails方法。
            rpdsvc.addDetails(orderInfo, details, cus);
            // 6. 查询roomPredict_order表里最大的id -> 修改temp_order predict_order_id
            tepsvc.updateTempOrder(map.get("temp_order").toString());
            System.out.println("交易成功");

        } else {
            System.out.println("交易失败");
        }
        response.getWriter().write("success");
    }

    @RequestMapping("/pay")
    public void pay(String payMoney, String orderNumber, HttpServletResponse response, HttpServletRequest request)
        throws IOException, AlipayApiException {
        AliPayDao aliPayDao = new AliPayDao();
        String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String seconds = new SimpleDateFormat("HHmmss").format(new Date());
        String temp = "http://" + request.getServerName() + ":80" + request.getContextPath();
        if ("localhost".equals(request.getServerName())) {
            WebInfoDao dao = new WebInfoDao();
            Map<String, Object> map = dao.findOne(null);
            temp = "http://" + map.get("domain").toString() + ":80" + request.getContextPath();
        }
        String notifyUrl = temp + "/desk/notifyPublicUrl";
        String returnUrl = temp + "/desk/returnPublicUrl";
        // 将支付信息存入temp_order表
        TempOrder tempOrder = new TempOrder();
        tempOrder.setName("");
        tempOrder.setPhone("");
        tempOrder.setRemark("");
        tempOrder.setRoom_type_id(1);
        tempOrder.setRoom_number(1);
        tempOrder.setIn_date(new Date());
        tempOrder.setOut_date(new Date());
        tempOrder.setTotal_price(new BigDecimal(payMoney));
        tempOrder.setTemp_order(orderNumber);
        tepsvc.insert(tempOrder);
        FastJsonJsonView view = new FastJsonJsonView();
        aliPayDao.SendAliPay(orderNumber, new BigDecimal(payMoney), "华悦假日酒店", returnUrl, notifyUrl, response);
    }

    @RequestMapping("/notifyPublicUrl")
    public void notifyPublicUrl(HttpServletRequest request, HttpServletResponse response, AliPayAccept aliPayAccept)
        throws Exception {
        // 支付成功
        if ("TRADE_SUCCESS".equals(aliPayAccept.getTrade_status())) {
            Map<String, Object> map = tepsvc.findTempOrder(aliPayAccept.getOut_trade_no());
            // 将支付信息存入alipay表中
            aliPayAccept.setOrderNumber(map.get("id").toString());
            aliPayDao.insert(aliPayAccept);
        }
        // System.out.println("支付成功");
        response.getWriter().write("success");
    }

    @RequestMapping("/returnPublicUrl")
    public void returnPublicUrl(HttpServletRequest request, HttpServletResponse response, AliPayAccept aliPayAccept)
        throws Exception {
        response.getWriter().write("<script>window.opener=null;window.close();</script>");
    }
}
